<?php


namespace Hilaoyu\LaravelExtend\Services\Files;


use Hilaoyu\LaravelPrivateApi\PrivateApiClient;
use Hilaoyu\Utils\UtilFile;
use Hilaoyu\Utils\UtilHttp;
use phpDocumentor\Reflection\Types\Resource_;

class FilesApiClient extends PrivateApiClient
{
    protected $client_config = [];
    public function __construct($client_config)
    {
        $this->client_config = $client_config;
        $uri = data_get($client_config,'service_uri');
        $secret = data_get($client_config,'secret');
        $app_id = data_get($client_config,'app_id');

        parent::__construct($uri, $secret, $app_id);
    }

    public function uploader(){
        if($this->request(data_get($this->client_config,'paths.uploader'))){
            return $this->getResult('data');
        }
        return false;
    }
    public function uploadTaskCreate(){
        if($this->request(data_get($this->client_config,'paths.upload_task_generate'))){
            return $this->getResult('data');
        }
        return false;
    }
    public function uploadTaskGet($id){
        if($id instanceof FilesModelAbstract){
            $id = $id->getKey();
        }
        if(!$id){
            $this->setError('参数错误');
            return false;
        }
        if($this->request(data_get($this->client_config,'paths.upload_task_get'),['id'=>$id])){
            return $this->getResult('data');
        }
        return false;
    }

    public function useFor($id){
        if($id instanceof FilesModelAbstract){
            $id = $id->getKey();
        }
        if(!$id){
            $this->setError('参数错误');
            return false;
        }
        if($this->request(data_get($this->client_config,'paths.usefor'),['id'=>$id])){
            return $this->getResult('data');
        }
        return false;
    }
    public function url(array $data){
        if($this->request(data_get($this->client_config,'paths.url'),$data)){
            return $this->getResult('data');
        }
        return false;
    }
    public function tempUrl(array $data){
        if($this->request(data_get($this->client_config,'paths.tempUrl'),$data)){
            return $this->getResult('data');
        }
        return false;
    }
    public function fileInfo(array $data){
        if($this->request(data_get($this->client_config,'paths.file_info'),$data)){
            return $this->getResult('data');
        }
        return false;
    }


    public function uploadFile(string  $file,$chunk_size=1024*1024){
        if($chunk_size <=0){
            $chunk_size=1024*1024;
        }
        $file_res = @fopen($file,'r');
        if(!$file_res){
            $this->setError('文件不可读');
            return false;
        }

        if(!$uploadr = $this->uploader()){
            return false;
        }

        $http_client = new UtilHttp($uploadr,'post');

        if(!$upload_task = $this->uploadTaskCreate()){
            return false;
        }

        $upload_task_id = data_get($upload_task,'id','');
        $total_size = filesize($file);

        $chunks = ceil($total_size/$chunk_size);

        $chunk = 0;
        $completed = false;
        while (!feof($file_res)) {
            $contents = fread($file_res, $chunk_size);
            $headers = [];
            $formData = UtilHttp::buildUploadFormDataAndHeaders(
                'upload_file',
                $contents,
                UtilFile::basename($file),
                [
                'task_id'=>$upload_task_id,
                'size'=>$total_size,
                'name'=>UtilFile::basename($file),
                'type'=>UtilFile::mimeType($file),
                'chunks'=>$chunks,
                'chunk'=>$chunk,
                'chunk_size'=>$chunk_size,
                'upload_file'=>null,
            ],$headers);

            //dump($formData,$headers);
            $result = $http_client->httpRequestJson('',$formData,'post',$headers);

            if(!$result){
                $this->setError($this->client->getError());
                break;
            }

            $status = data_get($result,'status');
            if(!$status){
                $errors = data_get($result,'errors');
                if(!empty($errors)){
                    $this->setError($errors);
                }
                break;
            }
            $result_data = data_get($result,'data');

            if('1' == data_get($result_data,'upload_is_completed')){
                $completed = true;
                break;
            }

            $chunk ++;
        }
        fclose($file_res);

        return $this->uploadTaskGet($upload_task_id);

    }
    
}